// utils/logger.js
// 日志工具模块

const fs = require('fs');
const path = require('path');

// 创建日志目录
const logDir = path.join(__dirname, '..', '..', 'logs');
if (!fs.existsSync(logDir)) {
    fs.mkdirSync(logDir, { recursive: true });
}

// 创建日志文件流
const backendLogStream = fs.createWriteStream(path.join(logDir, 'backend.log'), { flags: 'a' });
const errorLogStream = fs.createWriteStream(path.join(logDir, 'error.log'), { flags: 'a' });

// 确保日志流已准备好
backendLogStream.on('error', (err) => {
    console.error('后端日志流错误:', err);
});

errorLogStream.on('error', (err) => {
    console.error('错误日志流错误:', err);
});

// 获取调用栈信息的函数
function getCallerInfo() {
    const originalFunc = Error.prepareStackTrace;
    let callerfile;
    let callerline;
    
    try {
        const err = new Error();
        Error.prepareStackTrace = function (err, stack) {
            return stack;
        };
        
        const currentfile = err.stack.shift().getFileName();
        
        while (err.stack.length) {
            callerfile = err.stack.shift().getFileName();
            callerline = err.stack[0].getLineNumber();
            if (currentfile !== callerfile) break;
        }
    } catch (e) {
        // 忽略错误
    }
    
    Error.prepareStackTrace = originalFunc;
    
    // 将绝对路径转换为相对路径
    if (callerfile) {
        const rootDir = path.resolve(__dirname, '..');
        callerfile = path.relative(rootDir, callerfile);
    }
    
    return { file: callerfile, line: callerline };
}

// 获取北京时间
function getBeijingTime() {
    const now = new Date();
    // 转换为北京时间 (UTC+8)
    const beijingTime = new Date(now.getTime() + 8 * 60 * 60 * 1000);
    // 格式化为 YYYY-MM-DD HH:mm:ss.SSS
    return beijingTime.toISOString().replace('T', ' ').substring(0, 23);
}

// 日志级别
const LOG_LEVELS = {
    ERROR: 0,
    WARN: 1,
    INFO: 2,
    DEBUG: 3
};

// 当前日志级别（可以从环境变量获取，默认为INFO）
const CURRENT_LOG_LEVEL = process.env.LOG_LEVEL ? 
    LOG_LEVELS[process.env.LOG_LEVEL.toUpperCase()] : LOG_LEVELS.INFO;

// 获取日志前缀
function getLogPrefix(level, tag, file, line) {
    const fileInfo = file ? `${file}:${line}` : '';
    return `[${getBeijingTime()}] [${level}] ${tag ? `[${tag}] ` : ''}${fileInfo ? `[${fileInfo}] ` : ''}`;
}

// 写入日志到文件
function writeLogToFile(level, tag, message, data, file, line) {
    try {
        const prefix = getLogPrefix(level, tag, file, line);
        const logMessage = `${prefix}${message}\n`;
        
        // 写入后端日志文件
        if (backendLogStream.writable) {
            backendLogStream.write(logMessage);
        } else {
            console.warn('后端日志流不可写');
        }
        
        // 如果有附加数据，则以JSON格式输出
        if (data) {
            const dataMessage = `${prefix}Data: ${JSON.stringify(data, null, 2)}\n`;
            if (backendLogStream.writable) {
                backendLogStream.write(dataMessage);
            }
            
            // 错误信息同时写入错误日志文件
            if (level === 'ERROR') {
                if (errorLogStream.writable) {
                    errorLogStream.write(logMessage);
                    errorLogStream.write(dataMessage);
                } else {
                    console.warn('错误日志流不可写');
                }
            }
        }
        
        // 错误信息同时写入错误日志文件
        if (level === 'ERROR') {
            if (errorLogStream.writable) {
                errorLogStream.write(logMessage);
            } else {
                console.warn('错误日志流不可写');
            }
        }
    } catch (err) {
        console.error('写入日志文件时出错:', err);
    }
}

// 日志输出函数
function log(level, tag, message, data, file, line) {
    // 如果当前日志级别低于要输出的日志级别，则不输出
    if (CURRENT_LOG_LEVEL < LOG_LEVELS[level]) {
        return;
    }
    
    const prefix = getLogPrefix(level, tag, file, line);
    
    // 输出消息到控制台
    console.log(`${prefix}${message}`);
    
    // 写入日志到文件
    writeLogToFile(level, tag, message, data, file, line);
    
    // 如果有附加数据，则以JSON格式输出到控制台
    if (data) {
        console.log(`${prefix}Data: ${JSON.stringify(data, null, 2)}`);
    }
}

// 导出不同级别的日志函数
module.exports = {
    error: (tag, message, data) => {
        const { file, line } = getCallerInfo();
        log('ERROR', tag, message, data, file, line);
    },
    warn: (tag, message, data) => {
        const { file, line } = getCallerInfo();
        log('WARN', tag, message, data, file, line);
    },
    info: (tag, message, data) => {
        const { file, line } = getCallerInfo();
        log('INFO', tag, message, data, file, line);
    },
    debug: (tag, message, data) => {
        const { file, line } = getCallerInfo();
        log('DEBUG', tag, message, data, file, line);
    },
    
    // 中间件日志函数
    middleware: (tag, message, data) => {
        const { file, line } = getCallerInfo();
        log('INFO', `MW:${tag}`, message, data, file, line);
    },
    
    // 路由日志函数
    route: (tag, message, data) => {
        const { file, line } = getCallerInfo();
        log('INFO', `ROUTE:${tag}`, message, data, file, line);
    },
    
    // 数据库日志函数
    db: (tag, message, data) => {
        const { file, line } = getCallerInfo();
        log('INFO', `DB:${tag}`, message, data, file, line);
    },
    
    // 认证日志函数
    auth: (tag, message, data) => {
        const { file, line } = getCallerInfo();
        log('INFO', `AUTH:${tag}`, message, data, file, line);
    }
};